package com.zzp.controller;

import com.zzp.annotate.SubmitLimit;
import com.zzp.model.Student;
import com.zzp.service.StudentService;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.currentThread;

@RestController
@RequestMapping("/provider")
@RequiredArgsConstructor
public class ProviderController {

    private final StudentService studentService;

    private final StringRedisTemplate redisTemplate;

    private final RedissonClient redissonClient;

    // 查询所有学生
    @GetMapping("/students")
    public List<Student> getAllStudents() {
        return studentService.list();
    }

    // 查询单个学生
    @GetMapping("/students/{id}")
    public Student getStudentById(@PathVariable Integer id) {
        return studentService.getById(id);
    }

    @DeleteMapping("/delete/{id}")
    public Boolean deleteStudent(@PathVariable Integer id) {
        //阻塞十秒
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return studentService.removeById(id);
    }


    @PutMapping("/update")
    @SubmitLimit()
    public ResponseEntity<?> updateStudents(@RequestBody Student student) {
        String requestId = UUID.randomUUID().toString();
        String lockKey = "lock:updateStudents";

        // 尝试获取分布式锁
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofSeconds(10));
        if (acquired == null || !acquired) {
            // 获取锁失败，直接返回
            System.out.println("执行失败，" + currentThread().getName());
            return ResponseEntity.internalServerError().body("执行失败");
        }

        try {
            studentService.getById(student.getId());
            return ResponseEntity.ok("更新成功");
        } finally {
            redisTemplate.delete(lockKey);
        }
    }


    @PutMapping("/update/{id}")
//    @SubmitLimit(key = "${id}")
    public String updateStudentById(@PathVariable("id") Integer id) {

//        Student student = studentService.getById(id);
//        int i = Integer.parseInt(student.getAddress());
//        String address = String.valueOf(++i);
//        System.out.println("修改后："+address);
//        studentService.lambdaUpdate().set(Student::getAddress, address)
//                .eq(Student::getId, id)
//                .update();
//        return "更新成功";
        String requestId = UUID.randomUUID().toString();
        String lockKey = "lock:updateStudents";

        // 尝试获取分布式锁
//        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofSeconds(10));
//        if (acquired == null || !acquired) {
//            // 获取锁失败，直接返回
//            System.out.println("执行失败，" + currentThread().getName());
//            return "执行失败";
//        }
//
//        try {
//            Student student = studentService.getById(id);
//            System.out.println(student.getAddress());
//            int i = Integer.parseInt(student.getAddress());
//            String address = String.valueOf(++i);
//            System.out.println("修改后："+address);
//            studentService.lambdaUpdate().set(Student::getAddress, address)
//                    .eq(Student::getId, id)
//                    .update();
//
//            return "更新成功";
//        } finally {
//            redisTemplate.delete(lockKey);
//        }
        RLock lock = redissonClient.getLock(lockKey);
        boolean isLocked = false;
        try {
             isLocked = lock.tryLock();
            if (isLocked) {
                Thread.sleep(10000);
                Student student = studentService.getById(id);
                System.out.println(student.getAddress());
                int i = Integer.parseInt(student.getAddress());
                String address = String.valueOf(++i);
                System.out.println("修改后：" + address);
                studentService.lambdaUpdate().set(Student::getAddress, address)
                        .eq(Student::getId, id)
                        .update();

                return "更新成功";
            } else {
                // 获取锁失败，直接返回
                System.out.println("执行失败，" + currentThread().getName());
                return "执行失败";
            }
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
            return "执行失败";
        } finally {
            if (isLocked && lock.isHeldByCurrentThread()) { // 确保当前线程持有锁
                lock.unlock(); // 安全解锁
            }
        }


    }


}

